/**
 * 登录话务呼叫中心平台
 * @param deviceId 分机号
 * @param agentId 坐席工号
 * @param password 密码
 */
function login(deviceId, agentId, password) {
  ReasonCodeSign = '';
  console.warn(`${top.DateUtil.now() } 开始检查并退出CTI登录状态！`);
  console.warn(`${top.DateUtil.now() } : ${top.softphone.dealConnectors}`);
  const centerUrl = `${top.softphone.softPhonePath }/setAgentState?agentId=${agentId
  }&dealConnectors=${top.softphone.dealConnectors
  }&deviceId=${deviceId
  }&agentMode=Logout&func=Logout`;
  $.ajax({
    type: 'post',
    url: centerUrl,
    timeout: 3000,
    dataType: 'json',
    success(data) {
      if (data.code == 'OK') {
        console.warn(`${top.DateUtil.now()  } 呼叫中心强制退出成功`);
        loginCti(deviceId, agentId, password);
      } else {
        console.error(`${top.DateUtil.now()  } 呼叫中心强制退出失败:${  data.message}`);
        loginCti(deviceId, agentId, password);
      }
    },
    error(data) {
      console.error(`${top.DateUtil.now()  } 呼叫中心强制退出失败:${  data.statusText  }-${  data.responseText}`);
      loginCti(deviceId, agentId, password);
    },
  });
}

function loginCti(deviceId, agentId, password) {
  console.warn(`${top.DateUtil.now() }开始注册CTI！`);
  // 调用session的start接口连接服务器
  const startPromise = session.start(ctiConnectors);
  startPromise.then(() => 
        // 调用agent的signIn接口登录
         station.signIn(deviceId, agentId, password)
        // 登录成功的处理函数
    ).then((e) => {
    console.in('呼叫中心签入成功');
    if (callsWaiting && group.state === Station.PENDING && agent.queues[0]) {
      group.monitor(agent.queues[0].queueId);
    }
    // 登录失败的处理函数
  }).catch((e) => {
    session.end();
    console.error(`坐席签入呼叫中心CTI失败：${  e.message}`);
    top.softphone.showErrorInfo('坐席签入呼叫中心CTI失败', e.message, true);
  });
}


/*
 * 示闲-就绪
 */
function ready() {
  station.setMode(Agent.READY).then((e) => {
    widget.alert('就绪成功');
  }).catch((e) => {
    widget.error(e.message);
    console.error('坐席CTI就绪失败', e.message);
    top.softphone.showErrorInfo('坐席CTI就绪失败', e.message, true);
  });
}

/**
 * 示忙/小休
 * @param reason 小休原因
 */
function notReady(reason) {
  station.setMode(Agent.NOT_READY, {
    reason,
  }).then(() => {
    // ReasonCodeSign = reason;
    widget.alert('进入成功');
  }).catch((e) => {
    widget.error(e);
    top.softphone.showErrorInfo('坐席CTI未就绪操作失败', e.message, true);
  });
}

/**
 * 登出
 */
function logout() {
  station.signOut().then((e) => session.end()).then((e) => {
    console.warn(`${top.DateUtil.now()  }system: 坐席登出成功`);
  }).catch((e) => {
    widget.error(e.message);
    console.error(`${top.DateUtil.now()  }坐席CTI签出失败${  e.message}`);
    top.softphone.showErrorInfo('坐席CTI签出失败', e.message, true);
  });
}

/**
 * 应答电话
 */
function answer() {
  station.answer().then((e) => {
    console.warn('应答');
  }).catch((e) => {
    widget.error(e);
    top.softphone.showErrorInfo('坐席接起通话失败', e.message, true);
  });
}

/**
 * 外呼前先生成数据
 * @param number 电话号码
 */
function dialData() {
  const data = {};
  const sessionId = top.softphone.getOutBoundId();
  data.sessionId = sessionId;
  data.ucid = '';
  data.callId = '';
  data.callGroup = top.softphone.outboundGroup;
  data.autoAnswer = false;
  data.isTransferIvr = false;
  data.isconnected = false;
  data.isHangup = true;
  data.whoDropCall = '';
  for (const indNo in top.softphone.agentgroupList) {
    const groupObj = top.softphone.agentgroupList[indNo];
    if (groupObj.groupNo === top.softphone.outboundGroup) {
      data.autoAnswer = groupObj.groupAutoAnswer;
      data.callGroupVdn = groupObj.groupVDN;
    }
  }
  data.contactId = '';
  data.originalContactId = '00000000000000000000';
  data.timestamp = top.DateUtil.now('yyyy.MM.dd hh:mm:ss');
  data.ani = top.softphone.extNo;
  data.dnis = '';
  data.queue = '';
  data.direction = 'Out';
  data.sessionType = 'n';
  data.custData = {};
  data.custData.LANGUAGE = '0';
  data.custData.MSG = '';
  data.custData.EXTIDX = '2';
  data.custData.DNIS = '';
  data.custData.ANIS = '';
  data.custData.BNKNBR = top.softphone.tenantId;
  data.custData.BUSITYPE = '';
  data.custData.TRANSFBUSTYPE = '';
  data.custData.MENUID = '';
  data.custData.TRNDRI = '0';
  data.custData.TRNCNT = '1';
  data.custData.ACTYPE = '1';// "9";
  data.custData.MSGID = '';
  data.custData.CARD = '6250520500008934';// "";
  data.custData.IDTYPE = '';
  data.custData.IDNO = '';
  data.custData.AUTH = '';
  data.custData.CALLSTATUS = '0';
  data.custData.USERINFO = 'null|8|null|null';
  data.custData.NAME = '';
  data.custData.ENNAME = '';
  data.custData.HOMETELNO = '';
  data.custData.MOBILEPHONE = '';
  data.custData.CUSTNO = '';
  data.custData.OPERATETRAJECT = '';
  // console.info('out dialData:', data);
  top.softphone.sessionMap[sessionId] = data;
  // 振铃弹屏
  top.softphone.openNewSession(data);
  top.softphone.showErrorInfo('外呼弹屏', sessionId, true);
}

/**
 * 拨打电话-直接外拨按钮外呼
 * @param number 电话号码
 */
function dial(number) {
  station.dial(number).then((e) => {
    console.warn(`外拨:${  JSON.stringify(e)}`);
    const sessionId = top.softphone.currentSessionId;
    top.softphone.sessionMap[sessionId].callId = e.callId;
    top.softphone.sessionMap[sessionId].ucid = e.properties.ucid;
    top.softphone.sessionMap[sessionId].dnis = number;
    top.softphone.ucidMap[e.properties.ucid] = sessionId;
    top.softphone.sessionMap[sessionId].contactId = e.properties.ucid;
    top.softphone.sessionMap[sessionId].isHangup = false;
    top.softphone.currentUcid = e.properties.ucid;
    top.softphone.currentContactId = e.properties.ucid;
    // 激活会话
    top.softphone.activeSession(sessionId);
    top.softphone.insertCallHistory(top.softphone.sessionMap[sessionId]);// 插入呼叫历史
    // console.info('out dial dialData:', top.softphone.sessionMap[sessionId]);
  }).catch((e) => {
    console.error(e);
    top.softphone.showErrorInfo('外拨电话失败', e.message, true);
  });
}

/**
 * 挂断电话
 */
function hangup() {
  station.drop().then((e) => {
    console.warn('挂断');
    top.softphone.sessionMap[top.softphone.currentSessionId].whoDropCall = 'agent';
  }).catch((e) => {
    widget.error(e);
    top.softphone.showErrorInfo('坐席挂机操作失败', e.message, true);
  });
}

/**
 * 电话保持
 */
function hold() {
  station.hold().then((e) => {
    console.warn('保持');
  }).catch((e) => {
    widget.error(e);
    top.softphone.showErrorInfo('坐席保持通话失败', e.message, true);
  });
}


/**
 * 电话恢复
 */
function retrieve() {
  station.retrieve().then((e) => {
    console.warn('恢复');
  }).catch((e) => {
    widget.error(e.message);
    top.softphone.showErrorInfo('坐席恢复通话失败', e.message, true);
  });
}


/**
 * 挂断其他电话-强拆
 */
function hangupOther(callId, extNo) {
  /* station.dropother(callId, extNo).then(function (e) {
        console.info('挂断');
    })['catch'](function (e) {
        widget.error(e);
    }); */
  // 发送消息
  return session.socket.send({
    method: 'clearConnection',
    object: 'cti',
    params: [{
      callId,
      deviceId: extNo,
    }],
  });
}

/*
 * 挂机后的处理
 */
function afterHangup(sessionId) {
  top.softphone.idleBtnStatusUpdate(true);
  top.softphone.holdBtnLabelUpdate('保持');
  top.softphone.holdBtnStatusUpdate(false);
  top.softphone.agentStatusTimeUpdate('挂机小结');
  top.softphone.sessionMap[sessionId].isHangup = true;
  const { whoDropCall } = top.softphone.sessionMap[sessionId];
  let msgContent = '';
  let custTelNo = top.softphone.sessionMap[sessionId].ani;
  if (top.softphone.sessionMap[sessionId].direction === 'out') {
    custTelNo = top.softphone.sessionMap[sessionId].dnis;
  }
  if (whoDropCall === 'notconnected') // 客户振铃挂断
  {
    msgContent = `客户[${  custTelNo  }]振铃时挂断了电话，您可以进行小结操作了！`;
  } else if (whoDropCall === 'cust') // 客户挂断电话
  {
    msgContent = `客户[${  custTelNo  }]挂断了电话，您可以进行小结操作了！`;
  } else if (whoDropCall === 'agent') // 坐席挂断电话
  {
    msgContent = `您挂断了客户[${  custTelNo  }]电话，可以进行小结操作了！`;
  } else if (whoDropCall === 'IVRdiverted') // IVR转回未接起
  {
    msgContent = `您未接起客户[${  custTelNo  }]从IVR回转的电话，请进行小结操作！`;
  } else if (whoDropCall === 'diverted') // 新客户振铃未接起
  {
    msgContent = `您未接起客户[${  custTelNo  }]的电话，请进行小结操作！`;
  } else if (whoDropCall === 'transfer') // 转接给其他坐席
  {
    msgContent = `您已将客户[${  custTelNo  }]电话转接给其他坐席，请进行小结操作！`;
  } else if (whoDropCall === 'skillNo') // 转接其他技能组
  {
    msgContent = `您已将客户[${  custTelNo  }]电话转接给其他技能组，请进行小结操作！`;
  } else if (whoDropCall === 'telNo') // 转接外线
  {
    msgContent = `您已将客户[${  custTelNo  }]电话转接给其他外线电话，请进行小结操作！`;
  } else if (whoDropCall === 'SAT') // 转接满意度
  {
    msgContent = `客户电话[${  custTelNo  }]已转接满意度，请进行小结操作！`;
  } else if (whoDropCall === 'IVR') // IVR中异常挂机
  {
    msgContent = `客户[${  custTelNo  }]电话在IVR自助语音中异常挂断，请先进行小结操作，然后可以回访客户确认问题！`;
  } else // 其他异常挂断
  {
    msgContent = `客户[${  custTelNo  }]电话异常挂断，请先完成小结操，可以回访客户确认问题！`;
  }
  top.softphone.updateCallHistory('hangup', top.softphone.sessionMap[sessionId]);// 更新呼叫历史
  top.softphone.callDropAfter(sessionId);
  top.softphone.showErrorInfo('挂机提示', msgContent, false);
}


/**
 * 会议
 * @param agentId 邀请加入会议的坐席ID
 * @param sessionId 会话id
 */
function conferenceAgent(agentId) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, top.softphone.sessionMap[sessionId].custData.MENUID, top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    const dataStr = `${top.softphone.sessionMap[sessionId].ani }|${top.softphone.sessionMap[sessionId].dnis }|${top.softphone.sessionMap[sessionId].callGroup }|${top.softphone.sessionMap[sessionId].direction}`;
    if (top.softphone.isCalling()) {
      station.consultation(agentId, {
        type: 'conference', userData: { map: { uui: ucid, type: 'c', d: dataStr } },
      }).then((e) => {
        console.warn('发起会议');
      }).catch((e) => {
        top.softphone.showErrorInfo('发起会议失败', e.message, true);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能发起会议！', true);
    }
  }
}

/**
 *完成会议
 */
function completeConference() {
  if (top.softphone.isCalling()) {
    station.conference({
      type: 'conference',
    }).then((e) => {
      console.warn('完成会议');
    }).catch((e) => {
      widget.error(e.message);
      top.softphone.showErrorInfo('完成会议失败', e.message, true);
    });
  } else {
    top.softphone.showErrorInfo('提示', '非通话中，不能完成会议！', true);
  }
}

/**
 * 转接
 * @param agentId 转接另一个坐席ID
 * @param sessionId 会话id
 */
function transferAgent(agentId) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, top.softphone.sessionMap[sessionId].custData.MENUID, top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    const dataStr = `${top.softphone.sessionMap[sessionId].ani }|${top.softphone.sessionMap[sessionId].dnis }|${top.softphone.sessionMap[sessionId].callGroup }|${top.softphone.sessionMap[sessionId].direction}`;
    if (top.softphone.isCalling()) {
      station.consultation(agentId, {
        type: 'transfer', userData: { map: { uui: ucid, type: 't', d: dataStr } },
      }).then((e) => {
        console.warn('发起转接');
      }).catch((e) => {
        widget.error(e.message);
        top.softphone.showErrorInfo('发起转接失败', e.message, true);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能发起转接！', true);
    }
  }
}
/**
 *完成转接
 */
function completeTransfer() {
  if (top.softphone.isCalling()) {
    station.transfer({
      type: 'transfer',
    }).then((e) => {
      console.warn('完成转接', e);
      top.softphone.sessionMap[top.softphone.currentSessionId].whoDropCall = 'transfer';
      // 转移出去，进行挂机处理
      console.warn('user.Transferred dropHandle: 转移出去，进行挂机处理');
      afterHangup(sessionId);// 挂机后操作
    }).catch((e) => {
      widget.error(e.message);
      top.softphone.showErrorInfo('完成转接失败', e.message, true);
    });
  } else {
    top.softphone.showErrorInfo('提示', '非通话中，不能完成转接！', true);
  }
}

/**
 * 技能组转接
 * skillNoVdn 要转接的技能组号VDN
 */
function skillTransfer(skillNoVdn) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, top.softphone.sessionMap[sessionId].custData.MENUID, top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    const dataStr = `${top.softphone.sessionMap[sessionId].ani }|${top.softphone.sessionMap[sessionId].dnis }|${top.softphone.sessionMap[sessionId].callGroup }|${top.softphone.sessionMap[sessionId].direction}`;
    if (top.softphone.isCalling()) {
      station.singleStepTransfer(skillNoVdn, {
        userData: { map: { uui: ucid, type: 'g', d: dataStr } },
      }).then((e) => {
        console.warn('转接技能组', e);
        top.softphone.sessionMap[sessionId].whoDropCall = 'skillNo';
        // 转移出去，进行挂机处理
        console.warn('user.Transferred dropHandle: 转移出去，进行挂机处理');
        afterHangup(sessionId);// 挂机后操作
      }).catch((e) => {
        widget.error(e.message);
        top.softphone.showErrorInfo('转接技能组失败', e.message, true);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能转接技能组！', true);
    }
  }
}

/**
 * 转接外线
 * telNo 要转接的外线号码
 */
function transferTelNo(telNo) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  station.singleStepTransfer(telNo, {
    type: 'transfer',
  }).then((e) => {
    console.warn('转接外线', e);
    top.softphone.sessionMap[sessionId].whoDropCall = 'telNo';
    // 转移出去，进行挂机处理
    console.warn('user.Transferred dropHandle: 转移出去，进行挂机处理');
    afterHangup(sessionId);// 挂机后操作
  }).catch((e) => {
    widget.error(e.message);
    top.softphone.showErrorInfo('转接外线失败', e.message, true);
  });
}


/**
 * 单步转接，转接IVR
 * @param menuId 业务转接代码：CONF907 - 信用卡身份验证身份验证
 *                      CONF807 - 借记卡身份验证
 *                      CONF707 - 村镇身份验证
 * @param carno 卡号
 * @param idNo 证件号
 * @param idType 证件类型
 * @param reseMblNo 手机号码
 * @param targetType 目标业务类型
 *
 */
function singleStepTransfer(menuId) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, menuId, top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    if (top.softphone.isCalling()) {
      station.singleStepTransfer(top.softphone.ivrVdnNo, { userData: { map: { uui: ucid } } }).then((e) => {
        console.warn('转接IVR', e);
        top.softphone.sessionMap[sessionId].isTransferIvr = true;
        top.softphone.checkCallIVRStatus(ucid);
        top.softphone.agentStatusTimeUpdate('IVR转接中');
        top.softphone.updateCallHistory('ivrbefore', top.softphone.sessionMap[sessionId]);// 更新通话历史
      }).catch((e) => {
        widget.error(e.message);
        top.softphone.showErrorInfo('转接IVR失败', e.message, true);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能转接电话！', true);
    }
  }
}

/**
 * 会议转接，转接IVR
 * @param menuId 业务转接代码：CONF907 - 信用卡身份验证身份验证
 *                      CONF807 - 借记卡身份验证
 *                      CONF707 - 村镇身份验证
 * @param carno 卡号
 * @param idNo 证件号
 * @param idType 证件类型
 * @param reseMblNo 手机号码
 * @param targetType 目标业务类型
 *
 */
function conferenceTransferIVR(menuId) {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, menuId, top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    if (top.softphone.isCalling()) {
      station.consultation(top.softphone.ivrVdnNo, { type: 'conference', userData: { map: { uui: ucid } } }).then((e) => {
        console.warn('会议转接IVR', e);
        top.softphone.sessionMap[sessionId].isTransferIvr = true;
        // top.softphone.checkCallIVRStatus(ucid);
        top.softphone.agentStatusTimeUpdate('会议IVR转接中');
        // completeConference();
      }).catch((e) => {
        widget.error(e.message);
        top.softphone.showErrorInfo('转接IVR失败', e.message, true);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能转接电话！', true);
    }
  }
}


/*
 * 转接满意度
 */
function satisfactionTransfer() {
  const sessionId = top.softphone.currentSessionId;
  const { ucid } = top.softphone.sessionMap[sessionId];
  const ivrsetDataResul = top.softphone.setSoftPhoneData(sessionId, 'SAT000', top.softphone.sessionMap[sessionId].custData.CARD, top.softphone.sessionMap[sessionId].custData.IDTYPE, top.softphone.sessionMap[sessionId].custData.IDNO);
  if (ivrsetDataResul) {
    if (top.softphone.isCalling()) {
      station.singleStepTransfer(top.softphone.ivrVdnNo, {
        userData: { map: { uui: ucid, v: satisfaction } },
      }).then((e) => {
        console.warn('满意度转接');
        // 转移出去，进行挂机处理
        console.warn('转接满意度后，进行挂机处理');
        top.softphone.sessionMap[sessionId].whoDropCall = 'SAT';
        afterHangup(sessionId);// 挂机后操作
      }).catch((e) => {
        widget.error(e.message);
      });
    } else {
      top.softphone.showErrorInfo('提示', '非通话中，不能转接满意度调查！', true);
    }
  }
}


/**
 * 同步话机状态
 */
function sync() {
  hangup();
  Promise.resolve().then(() => {
    if (session.state === Session.DEAD) {
      return session.start(dcmpAddr, connector);
    }
  }).then((e) => {
    if (station.state === Station.PENDING) {
      return station.monitor(localStorage.getItem('deviceId'));
    }
  }).then((e) => station.sync(localStorage.getItem('deviceId')))
    .then(() => {
      console.warn('同步');
      widget.alert('同步成功');
    })
    .catch((e) => {
      widget.error(e.message);
    });
}


function sleep(n) {
  const start = new Date().getTime();
  while (true) {
    if (new Date().getTime() - start > n) {
      break;
    }
  }
}
